package com.zkh360.service.message.auth;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.ConfigAttribute;
import org.springframework.security.access.SecurityConfig;
import org.springframework.security.web.FilterInvocation;
import org.springframework.security.web.access.intercept.FilterInvocationSecurityMetadataSource;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
import org.springframework.stereotype.Service;

import com.zkh360.service.message.domain.SysAuthorities;
import com.zkh360.service.message.mapper.AuthoritiesMapper;
import com.zkh360.service.message.mapper.ResourcesMapper;
import com.zkh360.service.message.model.SysResourcesVO;


@Service
public class MyInvocationSecurityMetadataSourceService implements FilterInvocationSecurityMetadataSource {

    private static Map<String, Collection<ConfigAttribute>> resourceMap = null;

    @Autowired
    private AuthoritiesMapper authoritiesMapper;

    @Autowired
    private ResourcesMapper resourcesMapper;

    private void loadResourceDefine() {

        // 在Web服务器启动时，提取系统中的所有权限。
        List<SysAuthorities> authoritiesList = authoritiesMapper.selectAll();

        /**//*
         * 应当是资源为key， 权限为value。 资源通常为url， 权限就是那些以ROLE_为前缀的角色。 一个资源可以由多个权限来访问。
         * sparta
         */
        resourceMap = new HashMap<>();
        for (SysAuthorities authority : authoritiesList) {
            ConfigAttribute ca = new SecurityConfig(authority.getAuthority_name());
            List<SysResourcesVO> resourcesList = resourcesMapper.loadResourcesByAuthority(authority.getAuthority_name());
            for (SysResourcesVO res : resourcesList) {
                /**//*
                 * 判断资源文件和权限的对应关系，如果已经存在相关的资源url，则要通过该url为key提取出权限集合，将权限增加到权限集合中。
                 * sparta
                 */
                if (resourceMap.containsKey(res.getResource_name())) {
                    Collection<ConfigAttribute> value = resourceMap.get(res.getResource_name());
                    value.add(ca);
                    resourceMap.put(res.getResource_name(), value);
                } else {
                    Collection<ConfigAttribute> atts = new ArrayList<>();
                    atts.add(ca);
                    resourceMap.put(res.getResource_name(), atts);
                }
            }
        }
    }

    @Override
    public Collection<ConfigAttribute> getAllConfigAttributes() {
        return null;
    }

    // 根据URL，找到相关的权限配置。
    @Override
    public Collection<ConfigAttribute> getAttributes(Object object) throws IllegalArgumentException {

        if(resourceMap == null) loadResourceDefine();

        FilterInvocation filterInvocation = (FilterInvocation) object;
        Iterator<String> ite = resourceMap.keySet().iterator();
        while (ite.hasNext()) {
            String requestURL = ite.next();
            RequestMatcher requestMatcher = new AntPathRequestMatcher(requestURL);
            if (requestMatcher.matches(filterInvocation.getHttpRequest())) {
                return resourceMap.get(requestURL);
            }
        }
        return null;
    }

    @Override
    public boolean supports(Class<?> arg0) {
        return true;
    }


}